/*
 * SubSonic - http://subsonicproject.com
 * 
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an 
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
*/

using System;
using System.CodeDom;
using System.IO;
using System.Text;
using System.Web.Compilation;
using System.Web.Hosting;
using SubSonic.Utilities;

namespace SubSonic
{
	/// <summary>
	/// Summary for the BuildProvider class
	/// </summary>
	public class BuildProvider : System.Web.Compilation.BuildProvider
	{
		/// <summary>
		/// Generates source code for the virtual path of the build provider, and adds the source code to a specified assembly builder.
		/// </summary>
		/// <param name="assemblyBuilder">The assembly builder that references the source code generated by the build provider.</param>
		public override void GenerateCode(AssemblyBuilder assemblyBuilder)
		{
			Utility.WriteTrace("Invoking BuildProvider");
			DataService.LoadProviders();
			ICodeLanguage language = new CSharpCodeLanguage();

			DirectoryInfo di = new DirectoryInfo(HostingEnvironment.ApplicationPhysicalPath + "\\App_Code");
			FileInfo[] fi = di.GetFiles("*.vb");
			if(fi.Length > 0)
				language = new VBCodeLanguage();

			StringBuilder code = new StringBuilder(language.DefaultUsingStatements);
			TurboCompiler tc = new TurboCompiler();

			// loop over the providers, and generate code for each
			foreach(DataProvider provider in DataService.Providers)
			{
				Utility.WriteTrace(String.Format("Creating code for {0}", provider.Name));
				string[] tableList = DataService.GetTableNames(provider.Name);
				string[] viewList = DataService.GetViewNames(provider.Name);

				foreach(string tbl in tableList)
				{
					TurboTemplate tt = CodeService.BuildClassTemplate(tbl, language, provider);
					tc.AddTemplate(tt);
					if(provider.GenerateODSControllers)
					{
						TurboTemplate tODS = CodeService.BuildODSTemplate(tbl, language, provider);
						tc.AddTemplate(tODS);
					}
				}

				foreach(string view in viewList)
				{
					TurboTemplate tt = CodeService.BuildViewTemplate(view, language, provider);
					tc.AddTemplate(tt);
				}

				tc.AddTemplate(CodeService.BuildSPTemplate(language, provider));
				tc.AddTemplate(CodeService.BuildEnumTemplate(language, provider));
			}

			if(DataService.Providers.Count > 0)
				tc.AddTemplate(CodeService.BuildStructsTemplate(language, DataService.Provider));

			foreach(TurboTemplate tt in tc.Templates)
				tt.AddUsingBlock = false;
			tc.Run();

			foreach(TurboTemplate tt in tc.Templates)
				code.Append(tt.FinalCode);

			assemblyBuilder.AddCodeCompileUnit(this, new CodeSnippetCompileUnit(code.ToString()));
		}
	}
}